import os.path
from typing import Tuple, List

import gradio as gr
from gradio.themes.utils import colors

try:
    from bot.openai_bot import OpenAIBot
    from conf.config import BASE_DIR
    from service.baike_title_service import BaikeTitleService
    from utils.constants import TAGS
except ModuleNotFoundError:
    import os
    import sys
    sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))  # 离开IDE也能正常导入自己定义的包
    from bot.openai_bot import OpenAIBot
    from conf.config import BASE_DIR
    from service.baike_title_service import BaikeTitleService
    from utils.constants import TAGS


def get_predict_result(title: str, classifier_name: str, top_k: int = 10) -> Tuple[str, List]:
    """
    获取预测结果
    :param title: 百度标题
    :param classifier_name: 分类器名称
    :param top_k: 要返回排行前几的分类标签
    :return:
    """
    # 将标题向量化
    openai_bot = OpenAIBot()
    vector = openai_bot.embeddings(text_list=[title, ])[0]

    baike_title_service = BaikeTitleService()
    res_ls = baike_title_service.get_title_tags(title_vector=vector, top_k=top_k)

    # 结果解析
    predict_result = TAGS.get(res_ls[0].get("title_tag"))

    predict_result_details = list()
    for index, item in enumerate(res_ls):
        title = item.get("title")
        title_tag = TAGS.get(item.get("title_tag"))
        score = round(item.get("distance")*100, 2)
        predict_result_details.append([title, title_tag, score])

    return predict_result, predict_result_details


def main():
    with gr.Blocks(theme=gr.themes.Base(primary_hue=colors.emerald, secondary_hue=colors.green),
                   title="EasyClassifier") as app:
        gr.Markdown("# <center>Easy Classifier")

        with gr.Tab("百科标题分类"):
            # 输入组件
            ele_text_box_title = gr.Textbox(lines=1, label="输入待分类的百科标题", placeholder="请输入百科标题")

            with gr.Group():
                ele_radio_classifier = gr.Radio(["向量检索(推荐)", "随机森林"], value="向量检索(推荐)", interactive=False,
                                                label="选择分类器算法", info="暂支持向量检索、及机器学习-随机森林算法")

            # 输入示例
            gr.Examples(
                label="输入示例（点击某一行可快速填充上面的表单）",
                examples=[
                    ["想在武汉买房，需要什么前提条件", "向量检索(推荐)"],
                    ["房产证和不动产权证是不是一个证件？", "向量检索(推荐)"]
                ],
                inputs=[
                    ele_text_box_title, ele_radio_classifier
                ]
            )

            # 动作按钮
            ele_button = gr.Button("提交", variant="primary")

            # 输出组件
            ele_text_box_predict_result = gr.Textbox(label="预测的结果", lines=1)

            ele_dataframe_predict_result_details = gr.Dataframe(
                label="预测的详情",
                headers=["标题", "标签", "得分"],
                datatype=["str", "str", "str"],
                row_count=(1, "dynamic"),
                col_count=(3, "fixed"),
            )

            # 事件绑定
            ele_button.click(fn=get_predict_result,
                             inputs=[
                                 ele_text_box_title, ele_radio_classifier
                             ],
                             outputs=[ele_text_box_predict_result, ele_dataframe_predict_result_details, ])

        app.queue(concurrency_count=10)

        app.launch(show_api=False, server_name="0.0.0.0", server_port=9092,
                   favicon_path=os.path.join(BASE_DIR, "logo.png"))


if __name__ == '__main__':
    main()
